package com.woniuxy.consumeserver.listener;

import com.alibaba.fastjson2.JSONObject;
import com.rabbitmq.client.Channel;
import com.woniuxy.common.dto.SkuDto;
import com.woniuxy.common.dto.UserDto;
import com.woniuxy.consumeserver.service.FinanceConsumeService;
import com.woniuxy.consumeserver.service.FinancePayPlanService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

import static com.woniuxy.common.constant.FinanceConstant.RabbitMq.*;

@Component
@Slf4j
@AllArgsConstructor
public class ConsumeListener {


    @Autowired
    private FinanceConsumeService financeConsumeService;

    @Autowired
    private FinancePayPlanService financePayPlanService;
    
    @Autowired
    private StringRedisTemplate redisTemplate;

    public static final String CONSUME_QUEUE = "consume.queue";

//    @RabbitListener(queues = CONSUME_QUEUE)
//    public void consume(String json, Message message, Channel channel) {
//
//        try {
//            //把token拿出来进行判断在redis中是否有值
//            String messageId = message.getMessageProperties().getMessageId();
//            String token = redisTemplate.opsForValue().get(messageId);
//            //加分布式锁，保证线程安全
//            if(!StringUtils.isEmpty(token)){
//                JSONObject jsonObject = JSONObject.parseObject(json);
//                Long orderId = jsonObject.getLong(ORDER_ID);
//                SkuDto sku = jsonObject.getObject(SKU, SkuDto.class);
//                UserDto user = jsonObject.getObject(USER, UserDto.class);
//                //业务代码
//                financeConsumeService.payPlan(user.getId(), orderId, BigDecimal.valueOf(sku.getFinanceSkuPrice()));
//            }
//            //确认消息                                                           是否批量签收
//            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
//            redisTemplate.delete(messageId);
//        } catch (Exception e) {
//            log.error("consume is error:{}",e);
//            try {
//
//                //拒绝消息并且消息不保留，此时消息会丢失（如果有死信，会发送到死信队列）
//                //参数说明: 1.消息的tag（消息id具有唯一性）  2.multiple:是否批量拒绝   3.requeue:是否重新入队
//                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);//不常用
////            channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);//常使用
//            } catch (IOException ex) {
//                log.error("consume is error:{}",e);
//            }
//        }
//
//    }

    @RabbitListener(queues = CONSUME_QUEUE)
    public void consume(String json, Message message, Channel channel) {
        String messageId = message.getMessageProperties().getMessageId();
        try {
            //把token拿出来进行判断在redis中是否有值

            String token = redisTemplate.opsForValue().get(messageId);
            //加分布式锁，保证线程安全
            if(redisTemplate.delete(messageId)){
                JSONObject jsonObject = JSONObject.parseObject(json);
                Long orderId = jsonObject.getLong(ORDER_ID);
                SkuDto sku = jsonObject.getObject(SKU, SkuDto.class);
                UserDto user = jsonObject.getObject(USER, UserDto.class);
                //业务代码
                financeConsumeService.payPlan(user.getId(), orderId, BigDecimal.valueOf(sku.getFinanceSkuPrice()));
            }
            //确认消息                                                           是否批量签收
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            redisTemplate.delete(messageId);
        } catch (Exception e) {
            log.error("consume is error:{}",e);
            redisTemplate.opsForValue().set(messageId,messageId,30, TimeUnit.SECONDS);
            try {

                //拒绝消息并且消息不保留，此时消息会丢失（如果有死信，会发送到死信队列）
                //参数说明: 1.消息的tag（消息id具有唯一性）  2.multiple:是否批量拒绝   3.requeue:是否重新入队
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);//不常用
//            channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);//常使用
            } catch (IOException ex) {
                log.error("consume is error:{}",e);
            }
        }

    }

    @RabbitListener(queues = "rollback.consume.queue")
    public void rollbackPayPlan(String json,Message message, Channel channel) {
        try {
            JSONObject jsonObject = JSONObject.parseObject(json);
            BigDecimal sumPrice = jsonObject.getBigDecimal("sumPrice");
            Long orderId = jsonObject.getLong(ORDER_ID);
            Long userId = jsonObject.getLong(USER_ID);
            financePayPlanService.rollbackPayPlan(userId, sumPrice, orderId);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            try {
                log.error("rollbackConsume is error:{}",e);
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            } catch (IOException ex) {
                log.error("rollbackConsume is error:{}",e);
            }
        }

    }
}
